import { decryptAES, encryptAES } from '@/utils/encryption.js'
import Cookies from 'js-cookie'

// 抽离公共async错误捕获方法
export const awaitWrap = (promise) => {
  return promise
    .then(data => {
      return { err: null, res: data }
    })
    .catch(err => {
      return { err, res: null }
    })
}

// 判断是不是微信环境
export const isWechat = () => {
  const ua = navigator.userAgent.toLowerCase()
  return ua.includes('micromessenger')
}

/**
 * 判断是否为外部资源
 */
export function isExternal (path) {
  return /^(https?:|mailto:|tel:)/.test(path)
}

// 生成随机数
export const randomNum = (num, numArr) => {
  const letter = numArr || [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
  let i
  const text = []
  for (i = 0; i < num; i++) {
    text.push(letter[Math.floor(Math.random() * letter.length)])
  }
  return text.join('')
}

// 解析blob数据
export const parsingBlob = (blob) => {
  return new Promise(resolve => {
    const reader = new FileReader()
    reader.readAsText(blob, 'utf-8')
    reader.onload = () => {
      resolve(reader.result)
    }
  })
}

// 读取blob数据
export const readBlob = function (blob) {
  return new Promise((resolve, reject) => {
    parsingBlob(blob).then(result => {
      // 通过请求头去判断是不是报错文件
      const isErrorInfo = blob.type.includes('application/json')
      if (isErrorInfo) {
        const data = JSON.parse(result)
        reject(data.message || '出现错误')
      } else {
        resolve()
      }
    })
  })
}

// 防抖
export const debounce = (fn, delay) => {
  let timer = null
  return function () {
    if (timer) {
      clearTimeout()
    }
    timer = setTimeout(() => {
      fn.apply(this, arguments)
    }, delay)
    return timer
  }
}

/**
 * 生成到下载页面的query值，参数命名比较随意，为了防止参数名泄露
 * @param {String} type 下载类型
 * @param {String} param 下载的参数
 */
export const generateDownloadQuery = (type, param) => {
  const unionId = Cookies.get('unionId')
  const query = {
    type: encryptAES(type),
    ac: encryptAES(unionId)
  }
  if (param) {
    query.abc1 = encryptAES(JSON.stringify(param))
  }
  return query
}

/**
 * 解密下载页面的query值
 * @param {Object} query 下载页面的query值
 */
export const decryptDownloadQuery = (query) => {
  return new Promise((resolve, reject) => {
    try {
      const { type, ac, abc1 } = query
      const result = {
        unionId: decryptAES(ac),
        type: decryptAES(type),
        param: abc1 ? JSON.parse(decryptAES(abc1)) : null
      }
      resolve(result)
    } catch (e) {
      reject(e)
    }
  })
}

/**
 * 设置对象属性为空值
 * @param obj
 */
export const setDefaultEmptyValueForObject = function (obj) {
  Object.keys(obj).forEach(function (key) {
    if (obj[key] === null || obj[key] === '' || obj[key] === undefined) {
      obj[key] = '-'
    }
  })
}

// 下载文件
export const downloadFile = function (res, needDecode = true, filename) {
  if (!res.data) {
    return
  }
  const blob = new Blob([res.data])
  const contentDisposition = res.headers['content-disposition']
  let fileName = contentDisposition ? contentDisposition.substring(contentDisposition.indexOf('=') + 1) : '未命名.txt'
  fileName = filename || (needDecode ? decodeURIComponent(fileName) : fileName)
  if ('download' in document.createElement('a')) { // 不是IE浏览器
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.style.display = 'none'
    link.href = url
    link.setAttribute('download', fileName)
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link) // 下载完成移除元素
    window.URL.revokeObjectURL(url) // 释放掉blob对象
  } else { // IE 10+
    window.navigator.msSaveBlob(blob)
  }
}

/**
 * 计算对象存在多少存在值key的数量
 * @param obj 目标对象
 * @param excludeKeys Array 需要排除的key
 * **/
export const computeObjectValidKeyNum = (obj, excludeKeys = []) => {
  const keys = Object.keys(obj)
  const hasValueNum = []
  keys.forEach(k => {
    if (!excludeKeys.includes(k)) {
      const v = obj[k]
      // v = 0视为有true
      // v = [] 视为 false
      // !!v 视为true
      const isValidValue = v === 0 || (Array.isArray(v) ? v.length > 0 : !!v)
      if (isValidValue) {
        // console.log(k)
      }
      if (isValidValue) hasValueNum.push(k)
    }
  })
  return hasValueNum.length
}
